package org.nativejpa.transaction;

import com.atomikos.icatch.standalone.UserTransactionServiceFactory;
import com.atomikos.icatch.config.UserTransactionService;
import com.atomikos.icatch.config.imp.AbstractUserTransactionServiceFactory;

import javax.transaction.UserTransaction;
import javax.transaction.TransactionManager;
import javax.naming.Context;
import java.util.Properties;
import java.io.File;
import java.net.UnknownHostException;

/**
 * @author <a href="mailto:jfox.young@gmail.com">Young Yang</a>
 * @create 2009-3-24 13:39:53
 */
public class AtomikosTransactionManagerFactory extends TransactionManagerFactory {

    // check com.atomikos.icatch.standalone.UserTransactionServiceImp for configuration properties
    final static UserTransactionService uts = new UserTransactionServiceFactory().getUserTransactionService(getDefaultProperties());

    static TransactionManager tm;
    static UserTransaction utx;

    protected void setDefaultTransactionTimeout(int defaultTransactionTimeout) {
        //TODO:
    }

    public int getDefaultTransactionTimeout() {
        return 0;
    }
    
    public void init() {
        synchronized (AtomikosTransactionManagerFactory.class) {
            if (tm == null) {
                uts.init(uts.createTSInitInfo());
                tm = uts.getTransactionManager();
                utx = uts.getUserTransaction();
            }
        }
    }

    public void shutdown() {
        uts.shutdown(false);
    }

    public String getVendor() {
        return "Atomikos";
    }

    public Properties getProperties() {
        return uts.createTSInitInfo().getProperties();
    }

    public TransactionManager getVendorTransactionManager() {
        return tm;
    }

    private static Properties getDefaultProperties () {
        Properties ret = new Properties ();
        ret.setProperty ( AbstractUserTransactionServiceFactory.CONSOLE_FILE_NAME_PROPERTY_NAME, "tm.out" );
        ret.setProperty ( AbstractUserTransactionServiceFactory.OUTPUT_DIR_PROPERTY_NAME, "." + File.separator );
        ret.setProperty ( AbstractUserTransactionServiceFactory.LOG_BASE_DIR_PROPERTY_NAME, "." + File.separator );
        ret.setProperty ( AbstractUserTransactionServiceFactory.LOG_BASE_NAME_PROPERTY_NAME, "tmlog" );
        ret.setProperty ( AbstractUserTransactionServiceFactory.MAX_ACTIVES_PROPERTY_NAME, "50" );
        ret.setProperty ( AbstractUserTransactionServiceFactory.MAX_TIMEOUT_PROPERTY_NAME, "300000" );
        ret.setProperty ( AbstractUserTransactionServiceFactory.DEFAULT_JTA_TIMEOUT_PROPERTY_NAME, "10000" );
        ret.setProperty ( AbstractUserTransactionServiceFactory.CHECKPOINT_INTERVAL_PROPERTY_NAME, "500" );
        ret.setProperty ( UserTransactionServiceFactory.SERIAL_JTA_TRANSACTIONS_PROPERTY_NAME, "true" );
        // add unique tm name for remote usertx support
        ret.setProperty ( AbstractUserTransactionServiceFactory.TM_UNIQUE_NAME_PROPERTY_NAME, getDefaultName () );
        // indication of whether client tx demarcation is allowed
        ret.setProperty ( AbstractUserTransactionServiceFactory.CLIENT_DEMARCATION_PROPERTY_NAME, "false" );
        ret.setProperty ( Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.rmi.registry.RegistryContextFactory" );
        ret.setProperty ( AbstractUserTransactionServiceFactory.CONSOLE_LOG_LEVEL_PROPERTY_NAME, "WARN" );
        ret.setProperty ( Context.PROVIDER_URL, "rmi://localhost:1099" );

        // ADDED IN 2.0: automatic registration
        ret.setProperty (AbstractUserTransactionServiceFactory.AUTOMATIC_RESOURCE_REGISTRATION_PROPERTY_NAME, "true" );
        ret.setProperty ( AbstractUserTransactionServiceFactory.ENABLE_LOGGING_PROPERTY_NAME, "true" );

        ret.setProperty ( AbstractUserTransactionServiceFactory.CONSOLE_FILE_LIMIT_PROPERTY_NAME, "-1" );
        ret.setProperty ( AbstractUserTransactionServiceFactory.CONSOLE_FILE_COUNT_PROPERTY_NAME, "1" );

        ret.setProperty ( AbstractUserTransactionServiceFactory.THREADED_2PC_PROPERTY_NAME , "true" );
        ret.setProperty ( AbstractUserTransactionServiceFactory.REGISTER_SHUTDOWN_HOOK_PROPERTY_NAME , "false" );
        return ret;
    }

    private static String getDefaultName () {

        String ret = "tm";
        try {
            ret = java.net.InetAddress.getLocalHost ().getHostAddress ()
                    + ".tm";
        } catch ( UnknownHostException e ) {
            // ignore: use short default
        }

        return ret;
    }

}
